package cn.bitkit.component.task;

import cn.bitkit.base.dictionary.BasicTaskStatus;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public abstract class BaseTaskService<R extends BaseTaskData> {

    private final ReentrantLock taskLock = new ReentrantLock();
    protected R taskData;
    LongAdder errorCount = new LongAdder();
    volatile boolean errorBreaker = false;

    /**
     * 停止任务
     * @return 结果
     */
    public boolean stop(){
        log.info("stop...");
        if(taskData == null){
            return false;
        }
        taskData.setStatus(BasicTaskStatus.STOP.getCode());
        return true;
    }

    /**
     * 启动任务处理
     * @return 结果
     */
    public boolean start(R taskData){
        boolean res = taskLock.tryLock();
        if(!res){
            return false;
        }
        this.taskData = taskData;
        taskData.setStatus(BasicTaskStatus.RUNNING.code);
        taskData.setStatus(BasicTaskStatus.RUNNING.desc);
        try{
            log.info("doTask start:{}", taskData.getType());
            doTaskBefore();
            doTask();
            doTaskAfter();
            log.info("doTask end:{}", taskData.getType());
        } catch (Exception e) {
            log.error("doTask error:", e);
            taskData.setStatus(BasicTaskStatus.FAIL.code);
            taskData.setStatus(BasicTaskStatus.RUNNING.desc);
            return false;
        }finally {
            taskLock.unlock();
        }
        return true;
    }

    protected boolean isRunning(){
        return taskData != null && BasicTaskStatus.RUNNING.getCode().equals(taskData.getStatus()) && !errorBreaker;
    }

    protected void doTaskBefore(){

    }

    protected void doTaskAfter(){

    }

    /**
     * 处理数据
     */
    public abstract void doTask();

}
